package JUC_stady;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Project: tobe-better-coder
 * Package: JUC_stady
 *
 * @author : Mr.xu
 * @date : 2023/3/20 21:46
 */
public class LockSupportDemo {

    private volatile Object o = new Object();

    //    private Object o1 = new Object();
    public static void main(String[] args) {
//        method1();
//        method3();
        method4();
//        LockSupportDemo lockSupportDemo = new LockSupportDemo();
//        new Thread(() ->{
//            try {
//                lockSupportDemo.method();
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }).start();
//
//        new Thread(() ->{
//            try {
//                lockSupportDemo.method2();
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }).start();
    }

    public static void method1() {
        Object object = new Object();

        new Thread(() -> {
            synchronized (object) {
                System.out.println("线程" + Thread.currentThread().getName() + "进来了");
                try {
                    object.wait();//当前锁处于wait的状态的时候，别的线程可以获取这把锁？
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程" + Thread.currentThread().getName() + "被唤醒");
            }
        }, "t1").start();

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(() -> {
            synchronized (object) {
                object.notify();
                System.out.println("唤醒t1");
            }
        }, "t2").start();
    }

    public void method() throws InterruptedException {
        synchronized (o) {
            System.out.println("测试输出 -- come in");
            o.wait();
            System.out.println("接受指令。程序继续运行");
        }
    }

    public void method2() throws InterruptedException {
        synchronized (o) {
            System.out.println("发送唤醒请求");
            o.notify();
            System.out.println("请求发送完毕");
        }
    }

    public static void method3() {
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        new Thread(() -> {
            lock.lock();
            System.out.println(Thread.currentThread().getName() + "come in");
            try {
                condition.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "被唤醒");
            lock.unlock();
        }, "t1").start();

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(() -> {
            lock.lock();
            condition.signal();
            System.out.println(Thread.currentThread().getName() + "发出通知");
            lock.unlock();
        }, "t2").start();
    }

    public static void method4() {
        Thread t1 = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "come in");
            LockSupport.park();
            System.out.println(Thread.currentThread().getName() + "被唤醒");
        }, "t1");
        t1.start();

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + "...发出唤醒通知");
            LockSupport.unpark(t1);
            System.out.println(Thread.currentThread().getName() + "...发出唤醒通知成功");
        }, "t2").start();
    }
}